#include <iostream>
#include <time.h>
#include "Box.h"
#include "Population.h"
#include "Chromosome.h"
#include "Gene.h"



int main(int argc, char *argv[]) {
	
	Box *pBox;
	if( argc > 1 ){
		//std::cout<<argc<<" "<<argv[argc-1];
		string inputFile=argv[argc-1];
		pBox = new Box(inputFile);
	}
	else {
		pBox = new Box();
	}
	if( pBox == NULL )
		return 0;

	
	
	/*for(int i=0;i<50;i++){
		std::cout<<"Pop: "<<i<<":"<<std::endl;
		pPopulation->RISTransposition();
		if(pPopulation->checkPop("gpr") == 1)
			return 0;
		else 
			pPopulation->printPopulation();
	}
	return 0;*/
	/* DEBUG 
	Chromosome *chromo= new Chromosome( pBox);
	chromo->setGeneHead("++***",0);
	chromo->setGeneTail("xxxxxx",0);
	chromo->setGeneHead("++/xx",1);
	chromo->setGeneTail("xxxxxx",1);
	chromo->reTree();
	 --- */

	//pBox->SRloadData();
	pBox->FCPrint();
	pBox->printAttr();
	//pPopulation->checkPop("start");
	
	std::cout<<std::endl;



	


	std::cout<<std::endl;
	
	//std::cout<<"main: print poszlo"<<std::endl;

	vector<vector<vector<double>>> wyniki;

	for(int i=0;i<pBox->runs;i++) {
		Population *pPopulation = new Population( pBox , 1);
		if( pPopulation == NULL )
			return 0;
		vector<vector<double>> runWyniki;
		pPopulation->printPopulation();
		pPopulation->getFitness();
		pPopulation->printPopulationFitness();
		
		int N=0;	
		double maxFitness=pPopulation->getMaxFitnessValue();
		double avarage=pPopulation->getAvarageFitness();
		double trueMax = pBox->stopVal;
		int popNr=N;
		double bestFitness=maxFitness;
			vector<double> genWyniki;
			genWyniki.push_back(N);
			genWyniki.push_back(maxFitness);
			genWyniki.push_back(popNr);
			genWyniki.push_back(avarage);
			runWyniki.push_back(genWyniki);
			
		std::cout<<"populacja: "<<N<<", maxFitness:"<<maxFitness<<" od "<<popNr<<" populacji, srednio:"<<avarage<<std::endl;
		while(maxFitness<trueMax && N<pBox->generations-1){
			
			++N;
			std::cout<<"Run: "<<i<<" Gen:" <<N<<std::endl;
			Population *tmpPop=pPopulation->makeNew();
			pPopulation=tmpPop;

			pPopulation->getFitness();
		
			pPopulation->printPopulationFitness();
		
			maxFitness=pPopulation->getMaxFitnessValue();
			if(maxFitness>bestFitness){
				popNr=N;
				bestFitness=maxFitness;
				//std::cout<<"?? main: best:"<<bestFitness<<" max:"<< maxFitness<<std::endl;
			}
			double avarage=pPopulation->getAvarageFitness();
			std::cout<<"populacja: "<<N<<", maxFitness:"<<maxFitness<<" od "<<popNr<<" populacji, srednio:"<<avarage<<std::endl;
			vector<double> genWyniki;
			genWyniki.push_back(N);
			genWyniki.push_back(maxFitness);
			genWyniki.push_back(popNr);
			genWyniki.push_back(avarage);
			runWyniki.push_back(genWyniki);
			std::cout<<N<<" "<<maxFitness<<" "<<avarage<<std::endl;
		}
		std::cout<<std::endl;
		wyniki.push_back(runWyniki);
	}
	for(int i=0;i<pBox->runs;i++){
		double av=0;
		double total=0;
		for(int j=0;j<wyniki[i].size();j++){
			av+=wyniki[i][j][3];
			if(wyniki[i][j][1]==pBox->stopVal || j==wyniki[i].size()-1) 
				std::cout<<"Run: "<<i<<" Generacja: "<<j<<"\tBest: "<<wyniki[i][j][1]<<" od "<<wyniki[i][j][2]<<"/"<<wyniki[i][j][0]<<std::endl;
			//std::cout<<i<<"|"<<j<<"srednio: "<<wyniki[i][j][3]<<std::endl;
			total=j;
		}
		std::cout<<"\t\t:srednio: "<<av/total<<std::endl;
	}

} 